查看原文
其他

Python复杂网络结构可视化——matplotlib+networkx

DeepWeaver Python爱好者社区 2019-04-07

作者:DeepWeaver  Python爱好者社区专栏作者

知乎专栏:深度学堂

https://zhuanlan.zhihu.com/c_172487736


什么是networkx?


networkx在02年5月产生,是用python语言编写的软件包,便于用户对复杂网络进行创建、操作和学习。利用networkx可以以标准化和非标准化的数据格式存储网络、生成多种随机网络和经典网络、分析网络结构、建立网络模型、设计新的网络算法、进行网络绘制等。 ——百度百科


我们可以用networkx做什么?


https://networkx.github.io/documentation/stable/auto_examples/index.html


  1. 画图



2. 有向图,无向图,网络图……



3. 总之各种图


看到这你是不是心动了呢?今天的教程就是要教会你画出封面上的三层感知机模型图!


Let's get started!


首先导入networkx和matplotlib模块

import networkx as nx import matplotlib.pyplot as plt

>>> import networkx as nx >>> G = nx.Graph() 定义了一个空图 >>> G.add_node(1) 这个图中增加了1节点 >>> G.add_node('A') 增加'A'节点 >>> G.add_nodes_from([2, 3]) 同时加2和3两个节点 >>> G.add_edges_from([(1,2),(1,3),(2,4),(2,5),(3,6),(4,8),(5,8),(3,7)]) # 增加这么多条边,在下面有举例 >>> H = nx.path_graph(10) >>> G.add_nodes_from(H) >>> G.add_node(H) G.add_node('a')#添加点a G.add_node(1,1)#用坐标来添加点 G.add_edge('x','y')#添加边,起点为x,终点为y G.add_weight_edges_from([('x','y',1.0)])#第三个输入量为权值 #也可以 list = [[('a','b',5.0),('b','c',3.0),('a','c',1.0)] G.add_weight_edges_from([(list)])

我们来看看上面最后一句是什么意思

import matplotlib.pyplot as plt import networkx as nx H = nx.path_graph(10) G.add_nodes_from(H) nx.draw(G, with_labels=True) plt.show()



生成了标号为0到9的十个点!别急,丑是丑了点,一会我们再给他化妆。

#再举个栗子 G=nx.Graph() #导入所有边,每条边分别用tuple表示 G.add_edges_from([(1,2),(1,3),(2,4),(2,5),(3,6),(4,8),(5,8),(3,7)]) nx.draw(G, with_labels=True, edge_color='b', node_color='g', node_size=1000) plt.show() #plt.savefig('./generated_image.png') 如果你想保存图片,去除这句的注释


好了,你现在已经知道如何给图添加边和节点了,接下来是构造环:


画个圈圈

import matplotlib.pyplot as plt import networkx as nx # H = nx.path_graph(10) # G.add_nodes_from(H) G = nx.Graph() G.add_cycle([0,1,2,3,4]) nx.draw(G, with_labels=True) plt.show()


画个五角星

import networkx as nx import matplotlib.pyplot as plt #画图! G=nx.Graph() G.add_node(1) G.add_nodes_from([2,3,4,5]) for i in range(5):    for j in range(i):        if (abs(i-j) not in (1,4)):                G.add_edge(i+1, j+1) nx.draw(G,        with_labels=True, #这个选项让节点有名称        edge_color='b', # b stands for blue!        pos=nx.circular_layout(G), # 这个是选项选择点的排列方式,具体可以用 help(nx.drawing.layout) 查看     # 主要有spring_layout  (default), random_layout, circle_layout, shell_layout       # 这里是环形排布,还有随机排列等其他方式          node_color='r', # r = red        node_size=1000, # 节点大小        width=3, # 边的宽度       ) plt.show()

import random G = nx.gnp_random_graph(10,0.3) for u,v,d in G.edges(data=True):    d['weight'] = random.random() edges,weights = zip(*nx.get_edge_attributes(G,'weight').items()) pos = nx.spring_layout(G) nx.draw(G, pos, node_color='b', edgelist=edges, edge_color=weights, width=10.0, edge_cmap=plt.cm.Blues) # plt.savefig('edges.png') plt.show()

加入权重

import matplotlib.pyplot as plt import networkx as nx G = nx.Graph() G.add_edge('a', 'b', weight=0.6) G.add_edge('a', 'c', weight=0.2) G.add_edge('c', 'd', weight=0.1) G.add_edge('c', 'e', weight=0.7) G.add_edge('c', 'f', weight=0.9) G.add_edge('a', 'd', weight=0.3) elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5] esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5] pos = nx.spring_layout(G)  # positions for all nodes # nodes nx.draw_networkx_nodes(G, pos, node_size=700) # edges nx.draw_networkx_edges(G, pos, edgelist=elarge,                       width=6) nx.draw_networkx_edges(G, pos, edgelist=esmall,                       width=6, alpha=0.5, edge_color='b', style='dashed') # labels nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif') plt.axis('off') plt.show()

有向图

from __future__ import division import matplotlib.pyplot as plt import networkx as nx G = nx.generators.directed.random_k_out_graph(10, 3, 0.5) pos = nx.layout.spring_layout(G) node_sizes = [3 + 10 * i for i in range(len(G))] M = G.number_of_edges() edge_colors = range(2, M + 2) edge_alphas = [(5 + i) / (M + 4) for i in range(M)] nodes = nx.draw_networkx_nodes(G, pos, node_size=node_sizes, node_color='blue') edges = nx.draw_networkx_edges(G, pos, node_size=node_sizes, arrowstyle='->',                               arrowsize=10, edge_color=edge_colors,                               edge_cmap=plt.cm.Blues, width=2) # set alpha value for each edge for i in range(M):    edges[i].set_alpha(edge_alphas[i]) ax = plt.gca() ax.set_axis_off() plt.show()

颜色渐变的节点

import matplotlib.pyplot as plt import networkx as nx G = nx.cycle_graph(24) pos = nx.spring_layout(G, iterations=200) nx.draw(G, pos, node_color=range(24), node_size=800, cmap=plt.cm.Blues) plt.show()


颜色渐变的边

import matplotlib.pyplot as plt import networkx as nx G = nx.star_graph(20) pos = nx.spring_layout(G) colors = range(20) nx.draw(G, pos, node_color='#A0CBE2', edge_color=colors,        width=4, edge_cmap=plt.cm.Blues, with_labels=False) plt.show()


如何画一个多层感知机?

import matplotlib.pyplot as plt import networkx as nx left, right, bottom, top, layer_sizes = .1, .9, .1, .9, [4, 7, 7, 2] # 网络离上下左右的距离 # layter_sizes可以自己调整 import random G = nx.Graph() v_spacing = (top - bottom)/float(max(layer_sizes)) h_spacing = (right - left)/float(len(layer_sizes) - 1) node_count = 0 for i, v in enumerate(layer_sizes):    layer_top = v_spacing*(v-1)/2. + (top + bottom)/2.    for j in range(v):        G.add_node(node_count, pos=(left + i*h_spacing, layer_top - j*v_spacing))        node_count += 1 # 这上面的数字调整我想了好半天,汗 for x, (left_nodes, right_nodes) in enumerate(zip(layer_sizes[:-1], layer_sizes[1:])):    for i in range(left_nodes):        for j in range(right_nodes):            G.add_edge(i+sum(layer_sizes[:x]), j+sum(layer_sizes[:x+1]))     # 慢慢研究吧 pos=nx.get_node_attributes(G,'pos') # 把每个节点中的位置pos信息导出来 nx.draw(G, pos,        node_color=range(node_count),        with_labels=True,        node_size=200,        edge_color=[random.random() for i in range(len(G.edges))],        width=3,        cmap=plt.cm.Dark2, # matplotlib的调色板,可以搜搜,很多颜色呢        edge_cmap=plt.cm.Blues       ) plt.show()


差不多就是这个效果了。


后续我会封装为一个类,加入动态演示,比如通过颜色深浅,显示神经网络在优化的时候权重变化。应该会很好玩,嘿嘿。


上面你也可以改变layer_sizes


比如改为233333


调皮了

layter_sizes = [2, 3, 4, 5, 5, 4, 3, ] 贼丑了


完。

Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复“课程”即可获取:

小编的Python入门免费视频课程!!!

【最新免费微课】小编的Python快速上手matplotlib可视化库!!!

崔老师爬虫实战案例免费学习视频。

陈老师数据分析报告制作免费学习视频。

玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存